package com.mj.listen3.排序_数组;

public class _求数组小和 {

    public static void main(String[] args) {
        int[] arr = new int[]{1, 3, 4, 2, 5};
        System.out.println(mergeSort(arr, 0, arr.length));
    }

    /**
     * 对 [l, r) 范围内的数据进行归并排序; 左闭右开
     *
     * @param l
     * @param r
     */
    public static int mergeSort(int[] arr, int l, int r) {
        if (r - l < 2) return 0;// 至少要2个元素
        int mid = (r + l) >> 1;
        return mergeSort(arr, l, mid) + mergeSort(arr, mid, r) + merge(arr, l, mid, r);
    }

    /**
     * 对将 [l, m) 和 [m, r) 范围的有序序列合并成一个有序序列
     *
     * @param l
     * @param m
     * @param r
     */
    public static int merge(int[] arr, int l, int m, int r) {
        int[] help = new int[r - l];
        int i = 0;
        int p1 = l;
        int p2 = m;
        int res = 0;
        while (p1 < m && p2 < r) {
            res += arr[p1] < arr[p2] ? arr[p1] * (r - p2) : 0;
            help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        while (p1 < m) {
            help[i++] = arr[p1++];
        }
        while (p2 < r) {
            help[i++] = arr[p2++];
        }
        // 把数据放置回去
        for (i = 0; i < help.length; i++) {
            arr[l + i] = help[i];
        }
        return res;
    }
}
